<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Section 3.9.&nbsp; I/O Efficiency</title>
<link rel="STYLESHEET" type="text/css" href="images/style.css">
<link rel="STYLESHEET" type="text/css" href="images/docsafari.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch03lev1sec8.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch03lev1sec10.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<br><table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td valign="top"><a name="ch03lev1sec9"></a>
<h3 class="docSection1Title">3.9. I/O Efficiency</h3>
<p class="docText">The program in <a class="docLink" href="#ch03fig04">Figure 3.4</a> copies a file, using only the <tt>read</tt> and <tt>write</tt> functions. The following caveats apply to this program.</P>
<a name="ch03fig04"></a>
<H5 class="docExampleTitle">Figure 3.4. Copy standard input to standard output</h5>

<pre>
#include "apue.h"

#define BUFFSIZE 4096

int
main(void)
{
    int    n;
    char   buf[BUFFSIZE];

    while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) &gt; 0)
        if (write(STDOUT_FILENO, buf, n) != n)
            err_sys("write error");

    if (n &lt; 0)
        err_sys("read error");

    exit(0);
}
</pre><BR>


<UL><LI><p class="docList">It reads from standard input and writes to standard output, assuming that these have been set up by the shell before this program is executed. Indeed, all normal UNIX system shells provide a way to open a file for reading on standard input and to create (or rewrite) a file on standard output. This prevents the program from having to open the input and output files.</p></LI></UL>
<UL><li><p class="docList"><a name="idd1e19667"></a><a name="idd1e19672"></a><a name="idd1e19677"></a><a name="idd1e19683"></a><a name="idd1e19686"></a><a name="idd1e19691"></a><a name="idd1e19696"></a>Many applications assume that standard input is file descriptor 0 and that standard output is file descriptor 1. In this example, we use the two defined names, <tt>STDIN_FILENO</tt> and <tt>STDOUT_FILENO</tt>, from <tt>&lt;unistd.h&gt;</tt>.</P></li><LI><p class="docList">The program doesn't close the input file or output file. Instead, the program uses the feature of the UNIX kernel that closes all open file descriptors in a process when that process terminates.</P></LI><li><p class="docList">This example works for both text files and binary files, since there is no difference between the two to the UNIX kernel.</P></LI></ul>
<p class="docText">One question we haven't answered, however, is how we chose the <tt>BUFFSIZE</tt> value. Before answering that, let's run the program using different values for <tt>BUFFSIZE</tt>. <a class="docLink" href="#ch03fig05">Figure 3.5</a> shows the results for reading a 103,316,352-byte file, using 20 different buffer sizes.</P>
<p class="docText">The file was read using the program shown in <a class="docLink" href="#ch03fig04">Figure 3.4</a>, with standard output redirected to <tt>/dev/null</tt>. The file system used for this test was the Linux <tt>ext2</tt> file system with 4,096-byte blocks. (The <tt>st_blksize</tt> value, which we describe in <a class="docLink" href="ch04lev1sec12.html#ch04lev1sec12">Section 4.12</a>, is 4,096.) This accounts for the minimum in the system time occurring at a <tt>BUFFSIZE</tt> of 4,096. Increasing the buffer size beyond this has little positive effect.</P>
<p class="docText">Most file systems support some kind of read-ahead to improve performance. When sequential reads are detected, the system tries to read in more data than an application requests, assuming that the application will read it shortly. From the last few entries in <a class="docLink" href="#ch03fig05">Figure 3.5</a>, it appears that read-ahead in <tt>ext2</tt> stops having an effect after 128 KB.</p>
<a name="ch03fig05"></a><p><table cellspacing="0" class="allBorders" border="1" RULES="groups" cellpadding="5"><caption><h5 class="docTableTitle">Figure 3.5. Timing results for reading with different buffer sizes on Linux</h5></caption><colgroup><col width="75"><col width="75"><col width="75"><col width="75"><col width="100"></colgroup><thead><TR><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman"><tt>BUFFSIZE</tt></span></p></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">User CPU (seconds)</span></P></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">System CPU (seconds)</span></p></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">Clock time (seconds)</span></P></th><th class="bottomBorder thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">#loops</span></p></th></tr></thead><tr><td class="rightBorder" align="right" valign="top"><p class="docText">1</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">124.89</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">161.65</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">288.64</p></td><td class="docTableCell" align="right" valign="top"><p class="docText">103,316,352</p></TD></TR><tr><TD class="rightBorder" align="right" valign="top"><p class="docText">2</P></TD><td class="rightBorder" align="right" valign="top"><p class="docText">63.10</P></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">80.96</p></TD><td class="rightBorder" align="right" valign="top"><p class="docText">145.81</P></TD><TD class="docTableCell" align="right" valign="top"><p class="docText">51,658,#176</p></TD></TR><tr><TD class="rightBorder" align="right" valign="top"><p class="docText">4</P></td><td class="rightBorder" align="right" valign="top"><p class="docText">31.84</p></td><TD class="rightBorder" align="right" valign="top"><p class="docText">40.00</p></TD><td class="rightBorder" align="right" valign="top"><p class="docText">72.75</P></td><td class="docTableCell" align="right" valign="top"><p class="docText">25,829,088</p></td></tr><tr><td class="rightBorder" align="right" valign="top"><p class="docText">8</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">15.17</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">21.01</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">36.85</p></TD><TD class="docTableCell" align="right" valign="top"><p class="docText">12,914,544</p></TD></TR><TR><td class="rightBorder" align="right" valign="top"><p class="docText">16</P></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">7.86</p></TD><td class="rightBorder" align="right" valign="top"><p class="docText">10.27</P></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">18.76</p></TD><TD class="docTableCell" align="right" valign="top"><p class="docText">6,457,272</p></TD></TR><tr><td class="rightBorder" align="right" valign="top"><p class="docText">32</p></td><TD class="rightBorder" align="right" valign="top"><p class="docText">4.13</p></TD><td class="rightBorder" align="right" valign="top"><p class="docText">5.01</P></td><td class="rightBorder" align="right" valign="top"><p class="docText">9.76</p></td><td class="docTableCell" align="right" valign="top"><p class="docText">3,228,636</p></td></tr><tr><td class="rightBorder" align="right" valign="top"><p class="docText">64</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">2.11</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">2.48</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">6.76</p></TD><TD class="docTableCell" align="right" valign="top"><p class="docText">1,614,318</P></td></TR><TR><TD class="rightBorder" align="right" valign="top"><p class="docText">128</p></TD><td class="rightBorder" align="right" valign="top"><p class="docText">1.01</P></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">1.27</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">6.82</p></TD><TD class="docTableCell" align="right" valign="top"><p class="docText">807,159</p></td></tr><tr><TD class="rightBorder" align="right" valign="top"><p class="docText">256</p></TD><td class="rightBorder" align="right" valign="top"><p class="docText">0.56</P></td><td class="rightBorder" align="right" valign="top"><p class="docText">0.62</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">6.80</p></td><td class="docTableCell" align="right" valign="top"><p class="docText">403,579</p></td></tr><tr><td class="rightBorder" align="right" valign="top"><p class="docText">512</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">0.27</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">0.41</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">7.03</P></td><TD class="docTableCell" align="right" valign="top"><p class="docText">201,789</P></TD></tr><TR><td class="rightBorder" align="right" valign="top"><p class="docText">1,024</P></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">0.17</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">0.23</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">7.84</p></td><td class="docTableCell" align="right" valign="top"><p class="docText">100,894</p></TD></tr><TR><td class="rightBorder" align="right" valign="top"><p class="docText">2,048</P></td><td class="rightBorder" align="right" valign="top"><p class="docText">0.05</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">0.19</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">6.82</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">50,447</p></td></tr><tr><td class="rightBorder" align="right" valign="top"><p class="docText">4,096</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">0.03</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">0.16</P></td><TD class="rightBorder" align="right" valign="top"><p class="docText">6.86</P></TD><td class="docTableCell" align="right" valign="top"><p class="docText">25,223</P></td></TR><TR><TD class="rightBorder" align="right" valign="top"><p class="docText">8,192</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">0.01</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">0.18</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">6.67</p></TD><td class="docTableCell" align="right" valign="top"><p class="docText">12,611</P></td></TR><tr><td class="rightBorder" align="right" valign="top"><p class="docText">16,384</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">0.02</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">0.18</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">6.87</p></td><td class="docTableCell" align="right" valign="top"><p class="docText">6,305</p></td></tr><TR><TD class="rightBorder" align="right" valign="top"><p class="docText">32,768</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">0.00</P></td><TD class="rightBorder" align="right" valign="top"><p class="docText">0.16</P></TD><td class="rightBorder" align="right" valign="top"><p class="docText">6.70</P></td><TD class="docTableCell" align="right" valign="top"><p class="docText">3,152</P></TD></tr><TR><TD class="rightBorder" align="right" valign="top"><p class="docText">65,536</p></TD><TD class="rightBorder" align="right" valign="top"><p class="docText">0.02</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">0.19</p></TD><td class="rightBorder" align="right" valign="top"><p class="docText">6.92</P></td><TD class="docTableCell" align="right" valign="top"><p class="docText">1,576</p></td></tr><tr><td class="rightBorder" align="right" valign="top"><p class="docText">131,072</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">0.00</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">0.16</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">6.84</p></td><td class="docTableCell" align="right" valign="top"><p class="docText">788</P></TD></tr><TR><TD class="rightBorder" align="right" valign="top"><p class="docText">262,144</P></td><TD class="rightBorder" align="right" valign="top"><p class="docText">0.01</P></TD><td class="rightBorder" align="right" valign="top"><p class="docText">0.25</P></td><TD class="rightBorder" align="right" valign="top"><p class="docText">7.30</P></TD><td class="docTableCell" align="right" valign="top"><p class="docText">394</P></TD></tr><TR><TD class="rightBorder" align="right" valign="top"><p class="docText">524,288</p></td><td class="rightBorder" align="right" valign="top"><p class="docText">0.00</p></TD><td class="rightBorder" align="right" valign="top"><p class="docText">0.22</P></td><TD class="rightBorder" align="right" valign="top"><p class="docText">7.35</p></td><td class="docTableCell" align="right" valign="top"><p class="docText">198</p></td></tr></table></p><br>
<p class="docText">We'll return to this timing example later in the text. In <a class="docLink" href="ch03lev1sec14.html#ch03lev1sec14">Section 3.14</a>, we show the effect of synchronous writes; in <a class="docLink" href="ch05lev1sec8.html#ch05lev1sec8">Section 5.8</a>, we compare these unbuffered I/O times with the standard I/O library.</p>
<p class="docText"><a name="idd1e20294"></a><a name="idd1e20297"></a><a name="idd1e20300"></a><a name="idd1e20303"></a><a name="idd1e20308"></a><a name="idd1e20313"></a><a name="idd1e20316"></a><a name="idd1e20319"></a><a name="idd1e20322"></a><a name="idd1e20325"></a><a name="idd1e20328"></a><a name="idd1e20331"></a><a name="idd1e20334"></a><a name="idd1e20337"></a>Beware when trying to measure the performance of programs that read and write files. The operating system will try to cache the file incore, so if you measure the performance of the program repeatedly, the successive timings will likely be better than the first. This is because the first run will cause the file to be entered into the system's cache, and successive runs will access the file from the system's cache instead of from the disk. (The term <span class="docEmphasis">incore</span> means <span class="docEmphasis">in main memory</span>. Back in the day, a computer's main memory was built out of ferrite core. This is where the phrase &quot;core dump&quot; comes from: the main memory image of a program stored in a file on disk for diagnosis.)</p>
<p class="docText">In the tests reported in <a class="docLink" href="#ch03fig05">Figure 3.5</a>, each run with a different buffer size was made using a different copy of the file so that the current run didn't find the data in the cache from the previous run. The files are large enough that they all don't remain in the cache (the test system was configured with 512 MB of RAM).</p>

<ul></ul></td></tr></table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch03lev1sec8.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch03lev1sec10.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
</body></html><br>
<table width="100%" cellspacing="0" cellpadding="0"
style="margin-top: 0pt; border-collapse: collapse;"> 
<tr> <td align="right" style="background-color=white; border-top: 1px solid gray;"> 
<a href="http://www.zipghost.com/" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">The CHM file was converted to HTM by Trial version of <b>ChmD<!--45-->ecompiler</b>.</a>
</TD>
</TR><tr>
<td align="right" style="background-color=white; "> 
<a href="http://www.etextwizard.com/download/cd/cdsetup.exe" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">Download <b>ChmDec<!--45-->ompiler</b> at: http://www.zipghost.com</a>
</TD></tr></table>
